package com.panopset.flywheel.gui;

import static com.panopset.Util.*;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import com.panopset.flywheel.Flywheel;
import com.panopset.gui.TButton;
import com.panopset.gui.TPanel;
import com.panopset.gui.container.PanDirectory;
import com.panopset.gui.container.PanFile;

/**
 *
 * @author Karl Dinwiddie
 */
public class FlywheelMainApplicationPanel {

    private TPanel panel;
    private ScriptFileContainer scriptFileContainer;

    private ScriptFileContainer getScriptFileContainer() {
        if (scriptFileContainer == null) {
            scriptFileContainer = load();
        }
        return scriptFileContainer;
    }

    public TPanel getPanel() {
        if (panel == null) {
            panel = new TPanel.Builder().layout(new BorderLayout()).construct();
            panel.add(BorderLayout.NORTH,
                    assembleNorthLayout());
            panel.add(BorderLayout.CENTER, getWorkBench());
        }
        return panel;
    }

    private TPanel assembleNorthLayout() {
        TPanel rtn = new TPanel.Builder().layout(new GridLayout(5, 1)).construct();
        rtn.add(getScriptFileSelector().getPanel());
        rtn.add(getTargetDirectorySelector().getPanel());
        rtn.add(getPropertiesFileSelector().getPanel());
        TPanel buttons = new TPanel(new FlowLayout());
        buttons.add(getLoadButton());
        buttons.add(getSaveButton());
        buttons.add(getStepButton());
        buttons.add(getExecButton());
        getExecButton().setEnabled(false);
        getStepButton().setEnabled(false);
        rtn.add(buttons);
        TPanel cbtns = new TPanel(new FlowLayout());
        for (final Commenum commenum : Commenum.values()) {
            JButton btn = commenum.createButton();
            btn.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    userSelect(commenum.prototype);
                }

            });
            cbtns.add(btn);
        }
        JButton btn = new TButton("clear");
        btn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                userClear();
            }

        });
        cbtns.add(btn);
        rtn.add(cbtns);
        return rtn;
    }

    void userSelect(String prototype) {
        getScriptFileContainer().getTextArea().append(prototype);
    }

    void userClear() {
        getScriptFileContainer().getTextArea().setText(EMPTY_STRING);
    }

    private void step() {
        getScriptFileContainer().step();
    }

    private void exec() {
        load();
        getScriptFileContainer().exec();
    }

    private void save() {
        getScriptFileContainer().save();
    }

    public void quit() {
        getScriptFileContainer().quit();
    }

    public ScriptFileContainer load() {
        File scriptFile = getScriptFileSelector().getFile();
        File target = getTargetDirectorySelector().getFile();
        File properties = getPropertiesFileSelector().getFile();

        Flywheel flywheel = new Flywheel.Builder().file(scriptFile).targetDirectory(
                target).properties(properties).construct();
        ScriptFileContainer rtn = new ScriptFileContainer(flywheel);
        rtn.load();
        getExecButton().setEnabled(true);
        getStepButton().setEnabled(true);
        return rtn;
    }

    private TButton execButton;
    private TButton getExecButton() {
        if (execButton == null) {
            execButton = new TButton(x("Exec"), KeyEvent.VK_E,
                    "Execute template", new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    exec();
                }
            });
            execButton.setEnabled(false);
        }
        return execButton;
    }

    private TButton stepButton;
    private TButton getStepButton() {
        if (stepButton == null) {
            stepButton = new TButton(x("Step"), KeyEvent.VK_S,
                    "Execute template commands one at a time, for debugging.", new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    step();
                }
            });
            stepButton.setEnabled(false);
        }
        return stepButton;
    }

    private TButton loadButton;
    private TButton getLoadButton() {
        if (loadButton == null) {
            loadButton = new TButton(x("Load"), KeyEvent.VK_L, "Load template",
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            load();
                        }
                    });
        }
        return loadButton;
    }

    private TButton saveButton;
    private TButton getSaveButton() {
        if (saveButton == null) {
            saveButton = new TButton(x("Save"), KeyEvent.VK_S, x("Save templates"),
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            save();
                        }
                    });
        }
        return saveButton;
    }
    private PanFile propertiesFileSelector;

    private PanFile getPropertiesFileSelector() {
        if (propertiesFileSelector == null) {
            propertiesFileSelector = new PanFile(
                    x("Properties (optional)"),
                    x("optional properties file.  All properties available to variable commands."));
        }
        return propertiesFileSelector;
    }
    private PanFile targetDirectorySelector;

    private PanFile getTargetDirectorySelector() {
        if (targetDirectorySelector == null) {
            targetDirectorySelector = new PanDirectory(x("Target"),
                    x("target directory. All output will be relative to this directory."));
        }
        return targetDirectorySelector;
    }
    private PanFile scriptFileSelector;

    private PanFile getScriptFileSelector() {
        if (scriptFileSelector == null) {
            scriptFileSelector = new PanFile(x("Script File"),
                    x("Primary script file."));
        }
        return scriptFileSelector;
    }
    private JSplitPane workBench;

    public JSplitPane getWorkBench() {
        if (workBench == null) {
            workBench = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
            workBench.setDividerLocation(300);
            workBench.setOneTouchExpandable(true);
            workBench.add(new JScrollPane(getScriptFileContainer().getTextArea()));
            workBench.add(getScriptFileContainer().getInfrastructure().getPanel());
        }
        return workBench;
    }
}
